package com.xingfly.service.impl;

import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.apache.commons.collections.map.LinkedMap;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.TypeReference;
import com.xingfly.constant.AttributeConstant;
import com.xingfly.controller.TempController;
import com.xingfly.model.dto.Seat;
import com.xingfly.model.dto.Temp;
import com.xingfly.model.dto.User;
import com.xingfly.service.ArithmeticService;
import com.xingfly.service.SeatService;
import com.xingfly.service.TempService;
import com.xingfly.service.UserService;
import com.xingfly.suan.FlightArithmetic;
import com.xingfly.suan.flightMan;
@SuppressWarnings("all")
@Service("arithmeticService")
public class ArithmeticServicImpl implements ArithmeticService {
	@Resource
	private TempService tempService;
	@Resource
	private SeatService seatService;
	@Resource
	private UserService userService;
	
	private Logger logger = Logger.getLogger(TempController.class);//日志
	/**
	 * 单人分配算法
	 */
	@Override
	public String singleDistriBution(String users) {
		String result = "";
		float ztmyd = 0;
		float getSatis = 0;
		int jczrs = 0;
		int seid=0;
		int getuid=0;
		int getseid=0;
		com.xingfly.suan.Temp gettemp;
		try {
			// users 接收前台传过来的用户
			List<User> lus = JSON.parseObject(users, new TypeReference<List<User>>() {});
			// seat 查询出坐位表坐位状态为0的
			List<Seat> seas = seatService.SelBySeatAll(0);
			//查询用户状态为0的
			List<User> selBycond = userService.SelBycond(0);		
			// serial 组id
			int serial = tempService.selBySERIALMax();
			// 算法出现的结果
			Map<String, Object> allot = FlightArithmetic.Allot(lus, seas, serial);
			// 得出算法的本次分配满意度
			float satis = (float) allot.get("bcfpmyd");
			int uid = lus.get(0).getUid(); //查询出uid
			
			List<com.xingfly.suan.Temp>list = (List<com.xingfly.suan.Temp>)allot.get("tempData");
			for(int i=0;i<list.size();i++) {
				gettemp=list.get(i);
				getuid = gettemp.getUid();
				getseid =gettemp.getSeid();
				// 插入临时表
				int insertBysatis = tempService.insertBysatis(getuid, getseid, gettemp.getSerial(), gettemp.getSatis());
				//更改用户状态(用户表)
				int update = userService.update(1,getuid);
				//更改坐位表(座位表)
				int updateByUid = seatService.UpdateByUid(1, getseid);
			}
			// temp查询出临时表的状态
			List<Temp> selByAll = tempService.SelByAll();
			// 查出总条数
			float selByCount = tempService.selByCount();
			// 机舱总满意度
			for (int i = 0; i < selByAll.size(); i++) {
				getSatis += selByAll.get(i).getSatis();
			}
			float jczmyd = getSatis /selByCount; 
			// 总满意度等于个人满意度
			allot.put("bcfprs", lus.size());// 本次分配人数
			allot.put("jczrs", selByCount);// 机舱总人数
			allot.put("jczmyd", jczmyd); // 机舱总满意度
			allot.put("zhcj",((int)jczmyd)); //综合成绩
			result = JSONArray.toJSONString(allot);
		} catch (Exception e) {
			logger.debug("单人分配:"+AttributeConstant.ERROR);
			throw new RuntimeException(e);//回滚
		}
		return result;
	}
	/**
	 * 整仓分配
	 */
	@Override
	public String warehouse(){
		String result="";
		Map<String, Object> map = new HashMap<>();//总Map
		List<com.xingfly.suan.Temp> sum_tempData = new LinkedList<>();
		map.put("tempData",sum_tempData);
		try {
			//1.更改用户转态为0
			int updUserAll = userService.updUserAll();
			//2.更改坐位状态为0
			int updateByAllatstate = seatService.UpdateByAllatstate();
			//3.用户表查询
			List<Temp> temps = tempService.SelByAll();
			Collections.shuffle(temps);
			//4.删除temp表内容
			int deleteByAll = tempService.deleteByAll();
			//5.按照serial分组
			Map<Integer, List<User>> groupmap = new LinkedHashMap<Integer, List<User>>();
			
			//循环添加
			for(Temp t:temps) {
				User u = userService.SelByid(t.getUid()).get(0);
				int serial =t.getSerial();
				if(groupmap.containsKey(serial)) {
					groupmap.get(serial).add(u);
				}else {
					List<User>l=new LinkedList<>();
					l.add(u);
					groupmap.put(serial,l);
				}
			}
			//6.每一组用户送入算法,并操作数据库
			Map<String,Object> tempresultmap = null;//返回的前台所需map(需要累积起来)
			List<com.xingfly.suan.Temp> tempData = null;
			long sum_sfhs = 0;//定义-算法耗时(循环累加)
			int sum_ddcs = 0;//定义-迭代次数(循环累加)
			int sum_bcfprs = 0;//定义-本次分配满意度(循环累加)
			int sum_jczrs = 0;//定义-机舱总人数(最后数据库获取)
			float sum_bcfpmyd = 0.0f;//定义-本次分配满意度(循环累加除以 组数)
			float sum_jczmyd = 0.0f;//定义-机舱总满意度(最后数据库获取除以总人数)
			float sum_zhcj = 0.0f;//定义-综合成绩(强制类型转换jczmyd)
			//::::::::::::::::::::::::循环调用算法并累计计算各种复杂数据::::::::::::::::::::::::::::::::
			for(Entry<Integer,List<User>>e:groupmap.entrySet()) {
				tempresultmap=FlightArithmetic.Allot(e.getValue(),seatService.SelBySeatAll(0),e.getKey());//算法接口
				tempData=(List<com.xingfly.suan.Temp>)tempresultmap.get("tempData");
				//循环操作数据库ByTempPlues
				domysqlBytemp(tempData);
				//累加满意度
				sum_sfhs += (long)tempresultmap.get("sfhs");
				sum_ddcs += (int)tempresultmap.get("ddcs");
				sum_bcfpmyd += (float)tempresultmap.get("bcfpmyd")/groupmap.size();
				sum_bcfprs += tempData.size();
				//累加tempWithPrefer
				((List<com.xingfly.suan.Temp>)map.get("tempData")).addAll(tempData);
			}
			List<Temp> alltemp = tempService.SelByAll();
			for (Temp t : alltemp) {
				sum_jczmyd += t.getSatis()/alltemp.size();
			}
			sum_jczrs = alltemp.size();
			sum_zhcj = (int)sum_jczmyd;
			//3.put出前台所需值
			map.put("shfs", sum_sfhs);
			map.put("ddcs", sum_ddcs);
			map.put("bcfprs", sum_bcfprs);
			map.put("jczrs", sum_jczrs);
			map.put("bcfpmyd", (float)(Math.round(sum_bcfpmyd*100)/100));
			map.put("jczmyd", (float)(Math.round(sum_jczmyd*100)/100));
			map.put("zhcj", sum_zhcj);
			result = JSONArray.toJSONString(map);
		} catch (Exception e) {
			logger.debug("整仓分配:"+AttributeConstant.ERROR);
			e.printStackTrace();
			throw new RuntimeException(e);//回滚
		}
		return result;
	}
	
	private void domysqlBytemp(List<com.xingfly.suan.Temp> list) {
		for(int i=0;i<list.size();i++) {
			com.xingfly.suan.Temp temp=list.get(i);
			int uid = temp.getUid();
			int seid =temp.getSeid();
			int serial=temp.getSerial();
			float satis = temp.getSatis();
			// 插入临时表
			int insertBysatis = tempService.insertBysatis(uid,seid,serial,satis);
			//更改用户状态(用户表)
			int update = userService.update(1,uid);
			//更改坐位表(座位表)
			int updateByUid = seatService.UpdateByUid(1, seid);
		}
	}
	
}
